# Single-stage RAG: Good enough for prototypes
import openai
from chromadb import Client
class SimpleRAG:
def __init__(self, documents):
"""Initialize with a list of text documents."""
self.client = Client()
self.collection = self.client.create_collection("docs")
# Store documents with embeddings
self.collection.add(
documents=documents,
ids=[f"doc_{i}" for i in range(len(documents))]
)
def query(self, question: str, top_k: int = 3) -> str:
"""Retrieve relevant docs and generate answer."""
# Step 1: Retrieve relevant documents
results = self.collection.query(
query_texts=[question],
n_results=top_k
)
context = "\n\n".join(results['documents'][0])
# Step 2: Generate answer using retrieved context
response = openai.chat.completions.create(
model="gpt-4o",
messages=[
{
"role": "system",
"content": "Answer based only on the provided context. If the context doesn't contain the answer, say so."
},
{
"role": "user",
"content": f"Context:\n{context}\n\nQuestion: {question}"
}
],
temperature=0 # Deterministic for consistency
)
return response.choices[0].message.content
# Usage
documents = [
"RAG combines retrieval with generation...",
"Two-stage retrieval improves precision...",
# ... more docs
]
rag = SimpleRAG(documents)
answer = rag.query("What is two-stage retrieval?")
print(answer)